package info.webest.reminder.contacts;

import info.webest.reminder.Options;
import info.webest.reminder.wbDate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.text.format.DateFormat;
import android.util.Log;

/*
 If you need to read an individual contact, consider using CONTENT_LOOKUP_URI instead of CONTENT_URI. 
 If you need to look up a contact by the phone number, use PhoneLookup.CONTENT_FILTER_URI, which is optimized for this purpose. 
 If you need to look up a contact by partial name, e.g. to produce filter-as-you-type suggestions, use the CONTENT_FILTER_URI URI. 
 If you need to look up a contact by some data element like email address, nickname, etc, use a query against the ContactsContract.Data table. 
 The result will contain contact ID, name etc.
 */

public class ContactsReader {

	public static final String DATE_SORT_INDEX = "1MMdd";

	private Context context;

	public int todaySortIndex = 0;
	public Date today = null;

	public ContactsReader(Context context) {
		// Set context
		this.context = context;

		// todaySortIndex
		Calendar cal = Calendar.getInstance();
		today = (Date) cal.getTime();
		todaySortIndex = getTodaySortIndex();
	}

	public static int getTodaySortIndex() {

		Calendar cal = Calendar.getInstance();

		Date today = (Date) cal.getTime();
		SimpleDateFormat indexFormat = new SimpleDateFormat(DATE_SORT_INDEX,// yyyy
				Locale.getDefault());
		int sortIndex = Integer.valueOf(indexFormat.format(today));
		return sortIndex;
	}

	public List<Contact> getUpcomingEvents() throws Exception {

		List<Contact> list = new ArrayList<Contact>();

		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);

		String AccountName = prefs.getString(Options.ACCOUNT_NAME, null);
		String AccountType = prefs.getString(Options.ACCOUNT_TYPE, null);

		if (AccountName == null) {
			return list;
		}

		list = getContactList(AccountName, AccountType);
		for (int i = 0; i < list.size(); i++) {

			if (todaySortIndex > list.get(i).getSortIndex()) {
				list.remove(i);
				i--;
			} else if (list.get(i).getSortIndex() - todaySortIndex > 3) {
				list.remove(i);
				i--;
			}
		}

		Collections.sort(list, new Comparator<Contact>() {
			public int compare(Contact lhs, Contact rhs) {
				return lhs.getSortIndex() - rhs.getSortIndex();
			}
		});

		return list;
	}

	public List<Contact> getContactList(String AccountName, String AccountType) {

		List<Contact> list = new ArrayList<Contact>();
		String age = null;

		Uri uri = ContactsContract.Data.CONTENT_URI; // Data.CONTENT_URI

		String[] projection = new String[] { //
		ContactsContract.Contacts._ID,
				ContactsContract.CommonDataKinds.Event.CONTACT_ID,
				ContactsContract.CommonDataKinds.Event.DATA,
				ContactsContract.CommonDataKinds.Event.TYPE,
				ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Phone.NUMBER,
				ContactsContract.Contacts.PHOTO_ID,
				// ContactsContract.Data.DELETED,
				ContactsContract.Data.LOOKUP_KEY,
				ContactsContract.Data.MIMETYPE, };

		/*
		 * String where = ContactsContract.Data.MIMETYPE + "= ? AND " +
		 * extractDateInMM_DD(ContactsContract.CommonDataKinds.Event.START_DATE)
		 * + " >= ?" + " AND " +
		 * extractDateInMM_DD(ContactsContract.CommonDataKinds.Event.START_DATE)
		 * + " <= ?";
		 */

		/*
		 * String where = ContactsContract.Data.MIMETYPE + "= ? AND " +
		 * ContactsContract.CommonDataKinds.Event.TYPE + "=" +
		 * ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
		 */

		String where = "";
		String[] selectionArgs = null;

		if (AccountName != null && AccountName != "") {
			where = ContactsContract.Data.MIMETYPE
					+ "= ? AND "
					// + ContactsContract.Data.DELETED
					// + " IS NOT NULL AND "

					// + ContactsContract.CommonDataKinds.Event.DATA
					// + " IS NOT NULL AND "
					+ ContactsContract.RawContacts.ACCOUNT_NAME + " = ? AND "
					+ ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?";

			selectionArgs = new String[] {
					ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE,
					AccountName, AccountType };
		} else {
			where = ContactsContract.Data.MIMETYPE + "= ? AND "
					+ ContactsContract.CommonDataKinds.Event.DATA
					+ " IS NOT NULL ";

			selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
		}

		String sortOrder = null;
		// ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"

		ContentResolver cr = context.getContentResolver();

		Cursor phones = cr.query(uri, projection, where, selectionArgs,
				sortOrder);

		while (phones.moveToNext()) {

			String id = phones.getString(phones
					.getColumnIndex(ContactsContract.Data._ID));

			int contactId = phones.getInt(phones
					.getColumnIndex(ContactsContract.Data.CONTACT_ID));

			String name = phones
					.getString(phones
							.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

			int event_type = phones
					.getInt(phones
							.getColumnIndex(ContactsContract.CommonDataKinds.Event.TYPE));
			// vnd.android.cursor.item/contact_event
			// String mime_type = phones.getString(phones
			// .getColumnIndex(ContactsContract.Data.MIMETYPE));

			/*
			 * String phoneNumber = phones .getString(phones
			 * .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
			 */

			/*
			 * Birthday
			 */
			Date birthday = null;

			/*
			 * Age
			 */

			String shortDateFormat = "yyyy-MM-dd";
			// Settings.System.getString(
			// context.getContentResolver(), Settings.System.DATE_FORMAT);

			SimpleDateFormat dateFormat = new SimpleDateFormat(shortDateFormat,
					Locale.getDefault());

			String sDate = phones
					.getString(phones
							.getColumnIndex(ContactsContract.CommonDataKinds.Event.DATA));
			// phones.getColumnIndex(ContactsContract.CommonDataKinds.Event.DATA)

			// SimpleDateFormat formatter = new
			// SimpleDateFormat("dd-MMM-yyyy HH:mm");
			// String dateString = formatter.format(new
			// Date(Long.parseLong(lDate)));

			/*
			 * Format = android.text.format.DateFormat.getDateFormat(context
			 * .getApplicationContext()); String pattern = ((SimpleDateFormat)
			 * dateFormat) .toLocalizedPattern();
			 */

			try {
				birthday = (Date) dateFormat.parse(sDate);
				// System.out.println(date);
			} catch (ParseException e) {

				e.printStackTrace();

				SimpleDateFormat dateFormat2 = new SimpleDateFormat(
						"dd.MM.yyyy", Locale.getDefault());

				try {
					birthday = (Date) dateFormat2.parse(sDate);
				} catch (ParseException e2) {
					SimpleDateFormat dateFormat3 = new SimpleDateFormat(
							"MMM dd, yyyy", Locale.getDefault());

					try {
						birthday = (Date) dateFormat3.parse(sDate);
					} catch (ParseException e3) {

						if (sDate.startsWith("--")) {

							sDate = sDate.replace("--", "0000-");

							// date without year
							SimpleDateFormat dateFormat4 = new SimpleDateFormat(
									"yyyy-MM-dd", Locale.getDefault());

							try {
								birthday = (Date) dateFormat4.parse(sDate);
								// birthday.setYear(1);

							} catch (ParseException e4) {
								e4.printStackTrace();
							}
						} else {
							e3.printStackTrace();
						}
					}
				}

			}

			Log.d("birthday", name + " " + birthday);
			if (birthday != null) {

				int ageYears = wbDate.yearsSubstruct(birthday, today);

				int birthdayYear = Integer.valueOf((String) DateFormat.format(
						"yyyy", birthday));

				Contact contact = new Contact();
				contact.setDateWithYear(birthdayYear > 1);

				if (contact.getDateWithYear()) {
					age = "" + ageYears;
				} else {
					age = null;
				}

				SimpleDateFormat indexFormat1 = new SimpleDateFormat(
						DATE_SORT_INDEX, Locale.getDefault());
				int sortIndex = Integer.parseInt(indexFormat1.format(birthday));

				int month = Integer.valueOf((String) DateFormat.format("MM",
						birthday)) - 1;
				int day = Integer.valueOf((String) DateFormat.format("d",
						birthday));

				Log.v("name",
						"@@@ " + name + " ("
								+ DateFormat.format("yyyyy-MM-dd", birthday)
								+ ") m: " + month + " d: " + day);
				int interval = wbDate.daysBefore(month, day);

				//
				contact.setId(id);
				contact.setContactId(contactId);
				contact.setName(name);
				contact.setEventType(event_type);
				contact.setAge(age);
				contact.setEventDate(birthday);
				// contact.setDateWithYear(birthdayYear > 1);
				contact.setInterval(interval);
				contact.setSortIndex(sortIndex);
				list.add(contact);
			}
		}
		phones.close();
		return list;
	}
}
